home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
game
/
thomas
/
thomas.c
< prev
next >
Wrap
Text File
|
1993-07-08
|
13KB
|
535 lines
/**/
#include <stdio.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define COLMOS 14
#define COLWAK 32767
#define COLMEN 8
#define FILNLEN 128
#define GAMXSZ 240
#define GAMYSZ 240
#define SPXMAX 25
#define SPYMAX 25
#define STEP 8
#define DIRRIGHT 1
#define DIRUP 2
#define DIRLEFT 3
#define DIRDOWN 4
#define COMNOT 0
#define COMMOV 1
#define ABS(x) ((x)>0?(x):-(x))
#define SndWorkSize 16384
#define SNDDATASZ 64*1024
static char gwork[EgbWorkSize];
static char mwork[MosWorkSize];
static char swork[SndWorkSize];
static char snddata1[SNDDATASZ];
static char snddata2[SNDDATASZ];
static char sndname1[FILNLEN]="thomas1.snd";
static char sndname2[FILNLEN]="thomas2.snd";
static char tifname[FILNLEN]="thomas.tif"; /* default tif file name */
static int moshs=0,moshe=638,mosvs=0,mosve=478;
static char ramdata[GAMXSZ*GAMYSZ*2];
static int spx=4, spy=4, dotx, doty, datasize;
static int dir,rank,com;
static char map[SPYMAX][SPXMAX];
static int runflag=1;
/**/
int main(int argc, char *argv[])
{
option(argc,argv);
screen();
loadtif();
loadsnd();
mkmap();
main_process();
end();
return 0;
}
/**/
main_process()
{
int mb,mx,my;
while( runflag )
{
MOS_rdpos(&mb,&mx,&my);
switch(mb)
{
case 0: break;
case 1:
switch(getmos1(mx,my))
{
case COMMOV:movmap();
movpic();
break;
/* case COMEND:runflag=0;break; */
}
break;
case 2:
sndgo(20);
printhelp(mx,my);
break;
case 3: runflag=0; break;
default: break;
}
}
return 0;
}
/**/
option(int argc, char *argv[])
{
int i,j,l;
char s[FILNLEN+1];
for(i=1;i<argc;i++)
{
l=strlen(argv[i]);for(j=0;j<=l;j++) s[j]=tolower(argv[i][j]);
if( *s == '-' ) {option_size( argv[i] ); }
if( s[l-4]=='.' && s[l-3]=='t' && s[l-2]=='i' && s[l-1]=='f' )
{strcpy(tifname,s); }
if( s[l-4]=='.' && s[l-3]=='s' && s[l-2]=='n' && s[l-1]=='d' )
{strcpy(sndname2,sndname1);strcpy(sndname1,s); }
}
return 0;
}
option_size(char *s)
{
int sz;
sz=atoi(++s);
if(sz>16) sz=16;
if(sz< 3) sz= 3;
spx=spy=sz;
return 0;
}
loadsnd()
{
FILE *fp;
if( (fp=fopen(sndname1,"rb"))!=NULL)
{ fread(snddata1,sizeof(char),SNDDATASZ,fp);
if(DWORD(snddata1+12)>SNDDATASZ) DWORD(snddata1+12)=SNDDATASZ;
fclose(fp);}
if( (fp=fopen(sndname2,"rb"))!=NULL)
{ fread(snddata2,sizeof(char),SNDDATASZ,fp);
if(DWORD(snddata2+12)>SNDDATASZ) DWORD(snddata2+12)=SNDDATASZ;
fclose(fp);}
return 0;
}
/**/
sndgo(int n)
{
SND_pcm_play_stop(71);
switch(n)
{
case 0: SND_pcm_play(71,snddata1[28],127,snddata1);break;
case 1: SND_pcm_play(71,snddata2[28],127,snddata2);break;
case 20: SND_pcm_play(71,snddata2[28]+50,127,snddata2);break;
default: break;
}
return 0;
}
/**/
end()
{
MOS_end();
SND_end();
return 0;
}
/**/
screen()
{
EGB_init(gwork,EgbWorkSize); /* 画面初期化 */
EGB_resolution(gwork,0,3); /* page=0;mode */
EGB_writePage(gwork,0);
EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
EGB_displayStart(gwork,2,1,1); /* 拡大 */
EGB_displayStart(gwork,3,640,480); /* 画面のサイズ */
EGB_resolution(gwork,1,10); /* page=1;mode */
EGB_writePage(gwork,1);
EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
EGB_displayStart(gwork,2,2,2); /* 拡大 */
EGB_displayStart(gwork,3,320,240); /* 画面のサイズ */
EGB_displayPage(gwork,0,3); /* page0 前 page1,2表示 */
SND_init(swork);
/* SND_elevol_all_mute(0); */
SND_elevol_mute(1);
SND_pcm_mode_set(1);
MOS_start(mwork,MosWorkSize);
MOS_color(0,COLMOS);
MOS_horizon(moshs,moshe);
MOS_vertical(mosvs,mosve);
MOS_disp(1);
MOS_disp(3);
return 0;
}
/**/
loadtif()
{
N_tifLoad( tifname,1,0,0);
return 0;
}
/**/
mkmap()
{
int i,j,k;
dotx=GAMXSZ/spx; doty=GAMYSZ/spy;
datasize=dotx*doty*2;
char *ramp=ramdata;
for(j=0;j<spy;j++) for(i=0;i<spx;i++)
{ k=j*spx+i;
map[j][i]=k;
N_getBlock( ramp, i*dotx, j*doty, (i+1)*dotx-1, (j+1)*doty-1);
ramp+=datasize;
}
printmap();
return 0;
}
/**/
struct TIFTAG{
long tagtype;
long length;
long value;
} ;
/**/
N_tifLoad(char *filename,int page, int x, int y)
{
#define TIFWORKSIZE (320*240*2+0x0200)
char buf[TIFWORKSIZE];
struct TIFTAG * tag;
int i,ret;
int tagnum=0,sizex=0,sizey=0,doffs=0x0200;
ret=N_fload(filename, buf, TIFWORKSIZE);
tagnum=(int) WORD(buf+0x0008);
tag=(struct TIFTAG *) (buf+0x000a);
for(i=0;i<tagnum;i++)
{
switch(tag->tagtype)
{
case 0x00030100: sizex=tag->value;
break;
case 0x00030101: sizey=tag->value;
break;
case 0x00040111: doffs=tag->value;
break;
default: break;
}
tag++;
}
EGB_writePage(gwork,page);
EGB_writeMode(gwork,0);
N_putBlock( &buf[doffs], x, y, x+sizex-1, y+sizey-1);
return ret;
}
/**/
int N_fload(char *fname, char *buf, int bufsize)
{
FILE *fp1;
size_t fsize;
fp1=fopen(fname, "rb");
if (fp1==NULL) { fclose(fp1); return(-1); }
fsize=fread(buf, 1, bufsize, fp1);
fclose(fp1);
return((int) fsize);
}
/**/
int N_putBlock( char *ptn, int sx, int sy, int ex, int ey)
{
char gpara[14];
DWORD(gpara)=(unsigned int ) ptn;
WORD(gpara+4)=0x14;
WORD(gpara+6)=sx;
WORD(gpara+8)=sy;
WORD(gpara+10)=ex;
WORD(gpara+12)=ey;
return(EGB_putBlock(gwork,0,gpara));
}
/**/
int N_getBlock( char *ptn, int sx, int sy, int ex, int ey)
{
char gpara[14];
DWORD(gpara)=(unsigned int ) ptn;
WORD(gpara+4)=0x14;
WORD(gpara+6)=sx;
WORD(gpara+8)=sy;
WORD(gpara+10)=ex;
WORD(gpara+12)=ey;
return(EGB_getBlock(gwork,gpara));
}
getmos1(int x, int y)
{
int eb, ex, ey;
dir=0;
com=COMNOT;
while(MOS_rdpos(&eb,&ex,&ey),eb==1);
switch(eb)
{
case 0:
if(x<GAMXSZ*2 && y< GAMYSZ*2) {getdir(x,y,ex,ey);com=COMMOV;}
break;
case 1: break;
case 2: break;
case 3: runflag=0; return com;
default: break;
}
return com;
}
/**/
getdir(int x, int y, int ex, int ey)
{
int wx, wy, ws, wt;
wx=ABS(ex-x); wy=ABS(ey-y);
if( wx < 5 && wy < 5 )
{
wx=x-GAMXSZ; wy=y-GAMYSZ;
ws=wx-wy; wt=wx+wy;
if( ws>=0 && wt>=0 ) dir=DIRRIGHT; /* right */
if( ws>=0 && wt<=0 ) dir=DIRUP ; /* up */
if( ws<=0 && wt<=0 ) dir=DIRLEFT ; /* left */
if( ws<=0 && wt>=0 ) dir=DIRDOWN ; /* down */
}
else
{
wx=ex-x; wy=ey-y;
ws=wx-wy; wt=wx+wy;
if( ws>=0 && wt>=0 ) dir=DIRRIGHT; /* right */
if( ws>=0 && wt<=0 ) dir=DIRUP ; /* up */
if( ws<=0 && wt<=0 ) dir=DIRLEFT ; /* left */
if( ws<=0 && wt>=0 ) dir=DIRDOWN ; /* down */
}
switch(dir)
{
case DIRRIGHT:rank=y/doty/2;break;
case DIRUP :rank=x/dotx/2;break;
case DIRLEFT :rank=y/doty/2;break;
case DIRDOWN :rank=x/dotx/2;break;
}
return 0;
}
/**/
movmap()
{
int i,stnx,stny;
char xyb;
stnx=spx/3;
stny=spy/3;
switch(dir)
{
case DIRRIGHT:
if( rank<stny || spy-rank <= stny) return -1;
xyb=map[rank][spx-1];
for(i=spx-1;i>0;--i) map[rank][i]=map[rank][i-1];
map[rank][i]=xyb;
break;
case DIRUP:
if( rank<stnx || spx-rank <= stnx) return -1;
xyb=map[0][rank];
for(i=0;i<spy-1;i++) map[i][rank]=map[i+1][rank];
map[i][rank]=xyb;
break;
case DIRLEFT:
if( rank<stny || spy-rank <= stny) return -1;
xyb=map[rank][0];
for(i=0;i<spx-1;i++) map[rank][i]=map[rank][i+1];
map[rank][i]=xyb;
break;
case DIRDOWN:
if( rank<stnx || spx-rank <= stnx) return -1;
xyb=map[spy-1][rank];
for(i=spy-1;i>0;--i) map[i][rank]=map[i-1][rank];
map[i][rank]=xyb;
break;
}
return 0;
}
movpic()
{
int x1,y1,x2,y2,stnx,stny;
char para[64],buf[320*240*2];
stnx=spx/3;
stny=spy/3;
EGB_writePage(gwork,1);
if( rank<=0 ) goto error1;
switch(dir)
{
case DIRRIGHT:
if( rank<stny || spy-rank <= stny) goto error1;
{
sndgo(0);
x1=(spx-1)*dotx;x2=x1+dotx-1;y1=rank*doty;y2=y1+doty-1;
N_getBlock( buf, x1,y1,x2,y2);
WORD(para+0)=0;
WORD(para+2)=y1;
WORD(para+4)=x2;
WORD(para+6)=y2;
EGB_partScroll(gwork,0,dotx,0,para);
x1=0;x2=dotx-1;
N_putBlock( buf,x1,y1,x2,y2);
}
break;
case DIRUP:
if( rank<stnx || spx-rank <= stnx) goto error1;
{
sndgo(0);
x1=rank*dotx;x2=x1+dotx-1;y1=0;y2=doty-1;
N_getBlock( buf, x1,y1,x2,y2);
y1=(spy-1)*doty;y2=y1+doty-1;
WORD(para+0)=x1;
WORD(para+2)=0;
WORD(para+4)=x2;
WORD(para+6)=y2;
EGB_partScroll(gwork,0,0,-doty,para);
N_putBlock( buf,x1,y1,x2,y2);
}
break;
case DIRLEFT:
if( rank<stny || spy-rank <= stny) goto error1;
{
sndgo(0);
x1=0;x2=dotx-1;y1=rank*doty;y2=y1+doty-1;
N_getBlock( buf, x1,y1,x2,y2);
x1=(spx-1)*dotx;x2=x1+dotx-1;
WORD(para+0)=0;
WORD(para+2)=y1;
WORD(para+4)=x2;
WORD(para+6)=y2;
EGB_partScroll(gwork,0,-dotx,0,para);
N_putBlock( buf,x1,y1,x2,y2);
}
break;
case DIRDOWN:
if( rank<stnx || spx-rank <= stnx) goto error1;
{
sndgo(0);
x1=rank*dotx;x2=x1+dotx-1;y1=(spy-1)*doty;y2=y1+doty-1;
N_getBlock( buf, x1,y1,x2,y2);
WORD(para+0)=x1;
WORD(para+2)=0;
WORD(para+4)=x2;
WORD(para+6)=y2;
EGB_partScroll(gwork,0,0,doty,para);
y1=0;y2=doty-1;
N_putBlock( buf,x1,y1,x2,y2);
}
break;
}
return 0;
error1:
sndgo(1);return -1;
}
printmap()
{
int i,j;
char *ramp=ramdata;
for(j=0;j<spy;j++) for(i=0;i<spx;i++)
{ int x1,x2,y1,y2;
ramp=ramdata+datasize*map[j][i];
x1=i*dotx;y1=j*doty;x2=x1+dotx-1;y2=y1+doty-1;
EGB_writePage(gwork,1);
N_putBlock( ramp, x1, y1, x2, y2);
rectangle( x1,y1,x2,y2,0,COLWAK);
}
{
int stnx=spx/3,stny=spy/3;
char hat[]={0xff,0x00,0xff,0x00};
EGB_writePage(gwork,0);
EGB_hatchingPattern(gwork,2,1,4,hat);
EGB_paintMode(gwork,0x82);
EGB_color(gwork,2,COLMEN);
rectangle( 0, 0,stnx*dotx-1, stny*doty-1, 0,COLWAK);
rectangle( 0, (spy-stny)*doty, stnx*dotx-1, spy*doty-1, 0,COLWAK);
rectangle( (spx-stnx)*dotx, 0, spx*dotx-1, stny*doty-1, 0,COLWAK);
rectangle( (spx-stnx)*dotx,(spy-stny)*doty, spx*dotx-1, spy*doty-1, 0,COLWAK);
EGB_paintMode(gwork,0x02);
}
return 0;
}
rectangle(int x1, int y1, int x2, int y2, int page, int color)
{
MOS_disp(2);
char para[64];
EGB_writePage(gwork,page);
EGB_color(gwork,0,color);
WORD(para+0)=x1*2;
WORD(para+2)=y1*2;
WORD(para+4)=x2*2+1;
WORD(para+6)=y2*2+1;
EGB_rectangle(gwork,para);
MOS_disp(3);
return 0;
}
sjisStringCall(int x, int y, char *str)
{
char para[64];
WORD(para+0)=x;
WORD(para+2)=y+20;
WORD(para+4)=strlen(str);
strcpy(para+6,str);
MOS_disp(2);
EGB_sjisString(gwork,para);
MOS_disp(3);
return 0;
}
printhelp(int mx, int my)
{
char buf[TIFWORKSIZE];
int x1,y1,x2,y2,btn,x,y;
if( mx < 0 ) { x1= 0,x2=x1+320; }
else if(mx>639-320) {x2=639,x1=x2-320;}
else { x1=mx,x2=x1+320;}
if( my < 0 ) { y1= 0,y2=y1+164; }
else if(my>479-164) {y2=479,y1=y2-164;}
else { y1=my,y2=y1+164;}
EGB_writePage(gwork,0);
MOS_disp(2);
N_getBlock( buf, x1, y1, x2, y2);
MOS_disp(3);
EGB_writeMode(gwork,0);
EGB_paintMode(gwork,0x22);
rectangle( x1/2+1, y1/2+1, x2/2-1, y2/2-1, 0, 13);
EGB_color(gwork,0,15);
sjisStringCall(x1+16,y1 ," ==操作説明==");
sjisStringCall(x1+16,y1+ 20,"[左ボタンをドラッグする]");
sjisStringCall(x1+16,y1+ 40," ドラッグした方向に絵が動く。");
sjisStringCall(x1+16,y1+ 60," ただし、角の絵は動かせない。");
sjisStringCall(x1+16,y1+ 80,"[右ボタンを押し続ける]");
sjisStringCall(x1+16,y1+100," 操作説明画面が表示される。");
sjisStringCall(x1+16,y1+120,"[左右ボタン両方を押す]");
sjisStringCall(x1+16,y1+140," 終了する。");
while(MOS_rdpos(&btn,&x,&y),btn==2);
MOS_disp(2);
N_putBlock( buf, x1, y1, x2, y2);
MOS_disp(3);
return 0;
}